/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
 * MA  02110-1301, USA.
 *
 * http://www.gnu.org/copyleft/gpl.html
 */
package com.aionemu.gameserver.model.team;

import java.util.Collection;
import java.util.Map;

import javolution.util.FastList;
import javolution.util.FastMap;

import com.aionemu.gameserver.model.gameobjects.AionObject;
import com.aionemu.gameserver.model.gameobjects.instance.Kisk;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.team.interfaces.ITeamMember;
import com.aionemu.gameserver.network.aion.serverpackets.SM_SHOW_BRAND;
import com.aionemu.gameserver.utils.PacketSendUtility;

/**
 * @author lyahim
 *
 */
public abstract class Team<T extends ITeamMember> extends AionObject
{

	protected static Map<Integer, Team<?>>	teams	= new FastMap<Integer, Team<?>>().shared();

	public static Team<?> getTeamById(int id)
	{
		return teams.get(id);
	}

	private static void removeTeam(int id)
	{
		teams.remove(id);
	}

	public static void addTeam(Team<?> team)
	{
		teams.put(team.getObjectId(), team);
	}

	public static Collection<Team<?>> getPlayerTeams(Player player)
	{
		Collection<Team<?>> list = new FastList<Team<?>>();
		for (Team<?> memb : teams.values())
		{
			if (memb.isMember(player.getObjectId()))
				list.add(memb);
		}
		return list;
	}

	protected Integer					leader;
	protected final Map<Integer, Player>	onlineMembers	= new FastMap<Integer, Player>().shared();
	protected Map<Integer, T>		members	= new FastMap<Integer,T>().shared();
	protected Integer					kisk;

	public Team(int teamId, Integer leader)
	{
		super(teamId);
		addTeam(this);
		this.leader = leader;
	}

	public void setLeader(T newleader)
	{
		this.leader = newleader.getObjectId();
	}

	protected void addMember(T member)
	{
		members.put(member.getObjectId(), member);
	}

	/**
	 * @param members The members to set.
	 */
	public void setMembers(Map<Integer, T> members)
	{
		this.members = members;
	}

	protected void addOnlineMember(Player member)
	{
		onlineMembers.put(member.getObjectId(), member);
	}

	protected boolean isMember(T member)
	{
		return isMember(member.getObjectId());
	}

	protected boolean isMember(int memberId)
	{
		return members.containsKey(memberId);
	}

	protected void removeMember(T member)
	{
		removeMember(member.getObjectId());
	}

	protected void removeMember(int memberId)
	{
		onlineMembers.remove(memberId);
		members.remove(memberId);
	}

	public int size()
	{
		return members.size();
	}

	protected void onMemberLogOut(T member)
	{
		onMemberLogOut(member.getObjectId());
	}

	protected void onMemberLogOut(int memberId)
	{
		onlineMembers.remove(memberId);
	}

	public void showBrand(int brandId, int targetObjectId)
	{
		PacketSendUtility.broadcastPacketToTeam(null, this, new SM_SHOW_BRAND(brandId, targetObjectId));
	}

	protected Kisk getKisk()
	{
		return Kisk.getKiskById(kisk);
	}

	protected void deleteTeam()
	{
		members.clear();
		onlineMembers.clear();
		removeTeam(getObjectId());
	}

	public int getLeaderObjectId()
	{
		return leader;
	}
	
	public Collection<T> getMembers()
	{
		return members.values();
	}

	public Collection<Player> getOnlineMembers()
	{
		return onlineMembers.values();
	}

	public abstract boolean isFull();

	public abstract T getLeader();

	public abstract T getMemberById(int id);
	
	public abstract void onMemberLogIn(int objectId);
}
